package test.marui.com.mytest.view.layerView.view;

import android.support.annotation.NonNull;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

/**
 * Created by MR on 2019/1/21.
 */
class LayerManager implements View.OnKeyListener, ViewTreeObserver.OnGlobalFocusChangeListener, ViewTreeObserver.OnPreDrawListener {

    private ViewGroup mParent;
    private View mChild;

    private boolean isShowing;
    private boolean isDissmissing;
    private View mCurrentKeyView;
    private LiveListener mLiveListener;
    private boolean mCancelableOnClickKeyBack = true;

    LayerManager(@NonNull ViewGroup parent, @NonNull View child) {
        mParent = parent;
        mChild = child;
    }

    public void add() {
        if (mChild.getParent() != null) {
            return;
        }

        onAttach();
    }


    public void remove() {
        if (mChild.getParent() == null)
            return;

        onRemove();

    }

    public void setCancelableOnClickKeyBack(boolean mCancelableOnClickKeyBack) {
        this.mCancelableOnClickKeyBack = mCancelableOnClickKeyBack;
    }

    private void onAttach() {
        if (isShowing) {
            return;
        }

        isShowing = true;
        mParent.addView(mChild);
        mChild.setFocusable(true);
        mChild.setFocusableInTouchMode(true);
        mChild.requestFocus();
        mCurrentKeyView = mChild;
        mCurrentKeyView.setOnKeyListener(this);
        mChild.getViewTreeObserver().addOnGlobalFocusChangeListener(this);
        mChild.getViewTreeObserver().addOnPreDrawListener(this);
        if (mLiveListener != null) {
            mLiveListener.onAttach();
        }
    }

    private void onRemove() {
        if (isDissmissing)
            return;

        isDissmissing = true;
        mChild.postDelayed(new Runnable() {
            @Override
            public void run() {
                isDissmissing = false;
                onDetach();
            }
        }, onAnimOut(mChild) + 16);

        if (mLiveListener != null) {
            mLiveListener.onRemove();
        }

    }

    private long onAnimOut(View mChild) {
        if (mLiveListener != null) {
            return mLiveListener.onAnimOut(mChild);
        }
        return 0;
    }

    private void onDetach() {
        if (mCurrentKeyView != null) {
            mCurrentKeyView.setOnKeyListener(null);
        }

        mChild.getViewTreeObserver().removeOnGlobalFocusChangeListener(this);
        mParent.removeView(mChild);
        if (mLiveListener != null) {
            mLiveListener.onDetach();
        }
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {

        if (mChild.getParent() == null) {
            return false;
        }

        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {

                if (mCancelableOnClickKeyBack) {
                    remove();
                }

                return true;
            }
        }

        return false;
    }

    @Override
    public void onGlobalFocusChanged(View oldFocus, View newFocus) {

        if (mCurrentKeyView != null) {
            mCurrentKeyView.setOnKeyListener(null);
        }

        if (oldFocus != null) {
            oldFocus.setOnKeyListener(null);
        }

        if (newFocus != null) {
            mCurrentKeyView = newFocus;
            mCurrentKeyView.setOnKeyListener(this);
        }

    }

    @Override
    public boolean onPreDraw() {

        if (mChild.getViewTreeObserver().isAlive()) {
            mChild.getViewTreeObserver().removeOnPreDrawListener(this);
        }

        mChild.postDelayed(new Runnable() {
            @Override
            public void run() {
                isShowing = false;
                show();
            }
        }, onAnimIn(mChild) + 16);

        return false;
    }

    private long onAnimIn(View child) {
        if (mLiveListener != null) {
            return mLiveListener.onAnimIn(child);
        }
        return 0;
    }

    private void show() {
        if (mLiveListener != null) {
            mLiveListener.onShow();
        }
    }

    public void setLiveListener(LiveListener mLiveListener) {
        this.mLiveListener = mLiveListener;
    }

    public interface LiveListener {
        void onAttach();

        void onShow();

        long onAnimIn(View view);

        void onRemove();

        long onAnimOut(View view);

        void onDetach();
    }
}
